/**
 * 封装 axios 请求模块
 */
import axios from 'axios'
import store from '@/store'
import router from '@/router'
// 用来处理数字超过安全范围的方法
// import JSONBig from 'json-bigint'

const request = axios.create({
  baseURL: 'http://geek.itheima.net' // 基础路径
  // 自定义后端返回的原始数据 data：后端返回的原始数据，说白了就是 JSON 格式的字符串
  // transformResponse: [
  //   function (data) {
  //     try {
  //       // 使用JSONBig.parse处理大数字问题
  //       return JSONBig.parse(data)
  //     } catch (err) {
  //       // 如果转换失败，则包装为统一数据格式并返回
  //       return data
  //     }
  //   }
  // ]
})

// 请求拦截器
request.interceptors.request.use(
  function (config) {
    // 请求发起会经过这里
    // config：本次请求的请求配置对象
    const { user } = store.state
    if (user && user.token) {
      config.headers.Authorization = `Bearer ${user.token}`
    }
    // 注意：这里务必要返回 config 配置对象，否则请求就停在这里出不去了
    return config
  },
  function (error) {
    // 如果请求出错了（还没有发出去）会进入这里
    return Promise.reject(error)
  }
)

// 响应拦截器
request.interceptors.response.use(
  function (response) {
    // 第一个函数就是正常响应的时候要调用的函数
    return response
  },
  // 第二个函数时候响应出错的时候会执行的函数
  // 函数的形参error就是 响应时报的错误
  // 下面的if判断就是判断 错误的状态码是不是 401，如果是401代表就是token过期了
  async function (error) {
    if (error.response && error.response.status === 401) {
      // 获取到Vuex中保存的user用户数据，在user用户数据中包含了过期的token，和refresh_token
      const user = store.state.user
      if (!user || !user.refresh_token) {
        // 如果没有refresh_token就直接跳转到登录页面重新登录
        router.push('/login')
        return false
      }
      try {
        // 当我们请求刷新用户token的接口之后，接口返回的数据中就包含了 最新的token
        const res = await axios({
          method: 'PUT',
          url: 'http://geek.itheima.net/v1_0/authorizations',
          headers: {
            Authorization: `Bearer ${user.refresh_token}`
          }
        })
        console.log(res)
        // 将最新的token和refresh_token保存到Vuex中
        store.commit('setUser', {
          token: res.data.data.token,
          refresh_token: user.refresh_token
        })
        // error.config就是之前发生错误的那次请求的配置对象
        // 按照之前错误的那次请求的配置，重新请求一次
        return request(error.config)
      } catch (error) {
        router.push('/login')
      }
    } else {
      return Promise.reject(error)
    }
  }
)

export default request
